/**
 * 定义一系列辅助函数
*/


const toString = Object.prototype.toString

// 判断是否是日期类型
export function isDate(val: any): boolean {
  return toString.call(val) === '[object Date]'
}

// 判断是否是对象
export function isObject(val: any): boolean {
  return val !==null && typeof val === 'object'
}

// 判断是否普通对象(let obj = {name: xxx, age: xxx })
export function isPlainObject(val: any): boolean {
  return toString.call(val) === '[object Object]'
}

// 判断是URLSearchParams对象
export function isURLSearchParams(val: any): val is URLSearchParams {
  return typeof val !== 'undefined' && val instanceof URLSearchParams
}

// 将from对象中的属性和方法拷贝到to对象中
// for in 拷贝包括原型链中的属性和方法
export function extend<T,U>(to: T, from: U): T & U {
  for(let key in from) {
    ;(to as T & U)[key] = from[key] as any
  }
  return to as T & U;
}

export function deepMerge(...objs: any[]): any {
  const result = Object.create(null)
  
  // objs: [val1, val2]
  objs.forEach(obj => {
    if (obj) {
      Object.keys(obj).forEach(key => {
        const val = obj[key]
        if (isPlainObject(val)) {
          // header1和headers2中可能存在相同属性，不能覆盖掉
          if (isPlainObject(result[key])) {
            result[key] = deepMerge(result[key], val)
          } else {
            result[key] = deepMerge({}, val)
          }
        } else {
          result[key] = val
        }
      })
    }
  })

  return result
}

/** 判断ajax请求是否是同源请求： 这里只判断了协议和域名是否相同 */
interface URLOrigin {
  protocol: string
  host: string
}

const urlParsingNode = document.createElement('a')
// 当前调用页面地址
const currentOrigin = resolveURL(window.location.href)

function resolveURL(url: string): URLOrigin {
  urlParsingNode.setAttribute('href', url)
  const { protocol, host } = urlParsingNode

  return {
    protocol,
    host
  }
}

export function isURLSameOrigin(requestURL: string): boolean {
  const parsedOrigin = resolveURL(requestURL)
  return (
    parsedOrigin.protocol === currentOrigin.protocol && parsedOrigin.host === currentOrigin.host
  )
}


// export function isFormData(val: any): boolean {
  export function isFormData(val: any): val is FormData {  
  return typeof val !== 'undefined' && val instanceof FormData
}

// 判断ajax url是否是绝对路径
export function isAbsoluteURL(url: string): boolean {
  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}

export function combineURL(baseURL: string, relativeURL?: string): string {
  return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
}